﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using Newtonsoft.Json;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.ServiceComponent.DAC.Service;
using System.Reflection;

namespace T.FAS.Runtime.DataModel.Dao
{
    public class DatabaseELBDao : DaoService<Database>, IDatabaseDao
    {
        public const string MetaDataID = "Database";
        public const string MetaDataName = "数据库";
        public const string TenantID = "TenantID";
        public const string AppID = "AppID";
        public const string ModuleID = "ModuleID";
        public const string LastReleaseDatetime = "LastReleaseDatetime";

        public override string TableName => "FAS_Database";
        public override string IDColumnName => "ID";
        public override List<string> ExceptColumnName {get;} = new List<string>
        {
            "DatabaseConfigs",
        };

        private readonly DatabaseConfigELBDao _databaseConfigELBDao = new DatabaseConfigELBDao();

        public DatabaseELBDao() : base()
        {
            DBName = "TFAS";
        }

        public override Dictionary<string, PropertyInfo> GetColumns()
        {
            return DaoServiceExtension.GetAllColumns<Database>(base.GetColumns());
        }

        /// <summary>
        /// 获取元数据内容
        /// </summary>
        /// <param name="metaDataId"></param>
        /// <returns></returns>
        public List<Database> GetDatabases(Dictionary<string, string> filter)
        {
            var result = new List<Database>();
            if (filter == null)
            {
                return result;
            }
            List<string> tmp = new List<string>();
            if (filter.ContainsKey(IDColumnName))
                tmp.Add($" {IDColumnName}='{filter[IDColumnName]}' ");
            if (filter.ContainsKey(TenantID))
                tmp.Add($" {TenantID}='{filter[TenantID]}' ");
            if (filter.ContainsKey(AppID))
                tmp.Add($" {AppID}='{filter[AppID]}' ");
            if (filter.ContainsKey(ModuleID))
                tmp.Add($" {ModuleID}='{filter[ModuleID]}' ");
            if (filter.ContainsKey(LastReleaseDatetime))
                tmp.Add($" LastModifyTime>'{filter[LastReleaseDatetime]}' ");
            List<object> objects = base.GetObjectsByFilter(" 1=1 " + (tmp.Count > 0 ? "and " : "") + string.Join(" and ", tmp));
            if (objects != null)
            {
                objects.ForEach(obj => result.Add(obj as Database));
            }
            result.ForEach(db => db.DatabaseConfigs = _databaseConfigELBDao.GetDatabaseConfigs(new Dictionary<string, string> { { "ID", db.ID } }));
            return result;
        }

        public Database GetDatabaseByID(string databaseID)
        {
            var db = base.GetObject(databaseID);
            if (db == null)
                return null;
            db.DatabaseConfigs = _databaseConfigELBDao.GetDatabaseConfigs(new Dictionary<string, string> { { "ID", db.ID } });
            return db;
        }

        /// <summary>
        /// 删除Database
        /// </summary>
        /// <param name="Databases"></param>
        public void DeleteDatabase(string databaseID)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
            {
                _databaseConfigELBDao.DeleteDatabaseConfig(new Dictionary<string, string> { { "DatabaseID", databaseID } });
                base.Delete(new List<string> { databaseID });
                scope.Complete();
            }
        }

        public void AddDatabase(Database database)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
            {
                base.Add(new List<object> { database });
                //ArrayList arrayList = new ArrayList(database.DatabaseConfigs.Count);
                //database.DatabaseConfigs.ForEach(cfg => arrayList.Add(cfg));
                //DatabaseConfigELBDao.AddDatabaseConfigList(arrayList);
                scope.Complete();
            }
        }

        public void AddDatabaseList(List<Database> databaseList)
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                base.Add(new List<object>(databaseList));
                
                scope.Complete();
            }
        }

        public void UpdateDatabase(Database database)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
            {
                DeleteDatabase(database.ID);
                AddDatabase(database);

                scope.Complete();
            }
        }

        public void DeleteDatabase(Dictionary<string, string> filter)
        {
            var DatabaseID = filter["ID"];
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
            {
                _databaseConfigELBDao.DeleteDatabaseConfig(new Dictionary<string, string> { { "DatabaseID", DatabaseID } });
                base.Delete(new List<string> { DatabaseID });
                scope.Complete();
            }
        }


        /// <summary>
        /// 删除DB
        /// </summary>
        /// <param name="filter"></param>
        public void DeleteDatabaseList(List<string> idList)
        {
            Delete(idList);
            foreach (var DatabaseID in idList)
            {
                _databaseConfigELBDao.DeleteDatabaseConfig(new Dictionary<string, string> { { "DatabaseID", DatabaseID } });
            }
        }

        public int CheckUnique(Dictionary<string, string> filter)
        {
            string queryString =
                $@"Code='{filter["Code"]}' 
and DbType ='{filter["DbType"]}'
and TenantID ='{filter["TenantID"]}'
{(filter.Keys.Contains("ID") ? $"and ID != '{filter["ID"]}'" : "")}";
            var list = base.GetObjectsByFilter(queryString);
            return list == null ? 0 : list.Count;
        }
    }
}
